package com.bjy.qa.entity.mock.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bjy.qa.util.json.JsonHelper;
import lombok.Data;
import net.minidev.json.JSONArray;
import org.apache.commons.lang.StringUtils;

import java.util.*;

@Data
public class MockRequest {
    private MockContentType contentType; // 请求的 Content-Type
    private MockMethod Method; // 请求的方法
    private String url; // 请求的 URL
    private String uri; // 请求的 URI
    private String scheme; // 请求的 scheme
    private int localPort; // 请求的 localPort（应用服务器的端口。如果你请求的是 8080 但经过 nginx 转发到 80，那这里获得的是 80）
    private int serverPort; // 请求的 serverPort（请求URL中的端口。如果你请求的是 8080 但经过 nginx 转发到 80，那这里获得的是 8080）
    private int remotePort; // 请求的 remotePort（请求的客户端的端口）
    private String protocol; // 请求的 protocol（请求的协议，如 HTTP/1.1）
    private String host; // 请求的 host（请求的域名或 IP）
    private String remoteHost; // 请求的 remoteHost（请求的客户端的域名或 IP）
    private String remoteAddr; // 请求的 remoteAddr（请求的客户端的 IP）
    private Map<String, String> headers = new HashMap<>(); // 请求的 headers
    private Map<String, String> cookies = new HashMap<>(); // 请求的 cookies
    private Map<String, ArrayList<String>> params = new HashMap<>(); // 请求的 url 中的参数（queryString 请求的查询字符串）
    private Object body = null; // 请求的 body 参数

    /**
     * 返回指定 name 的 header
     * @param name header 名称
     * @return
     */
    public String getHeaders(String name) {
        return headers.get(name.toLowerCase());
    }

    /**
     * 返回指定 name 的 cookie
     * @param name cookie 名称
     * @return
     */
    public String getCookies(String name) {
        return cookies.get(name.toLowerCase());
    }

    /**
     * 返回请求的 url 中的参数值
     * @param key 参数名
     * @return
     */
    public String[] getParamsValue2Array(String key) {
        if (params.get(key) == null) {
            return null;
        } else {
            return params.get(key).toArray(new String[0]);
        }
    }

    /**
     * 返回请求的 url 中的参数值
     * @param key 参数名
     * @return
     */
    public List<String> getParamsValue2List(String key) {
        if (params.get(key) == null) {
            return null;
        } else {
            return params.get(key);
        }
    }

    /**
     * 返回请求的 url 中的一个参数值
     * @param key 参数名
     * @return
     */
    public String getParamsValue2String(String key) {
        if (params.get(key) == null) {
            return null;
        } else if (params.get(key).size() > 1) {
            throw new RuntimeException("参数值不唯一");
        } else if (params.get(key).size() == 1) {
            return params.get(key).get(0);
        } else {
            return null;
        }
    }

    /**
     * 获取请求的 body 中的参数值
     * @param key 参数名
     * @return
     */
    public String[] getBodyValue2Array(String key) {
        if (this.contentType == MockContentType.FORM_DATA || this.contentType == MockContentType.X_WWW_FORM_URLENCODED) {
            if (((JSONObject) body).getJSONArray(key) == null) {
                return null;
            } else {
                return ((JSONObject) body).getJSONArray(key).toArray(new String[0]);
            }
        } else if (this.contentType == MockContentType.JSON) {
            JsonHelper jsonHelper = new JsonHelper(JSON.toJSONString(this.body));
            ArrayList<String> tmp = new ArrayList<>();
            if (jsonHelper == null) {
                return null;
            }
            Object value = jsonHelper.get(key.trim());
            if (value == null) {
                return null ;
            } else if (value instanceof LinkedHashMap) {
                throw new RuntimeException("参数不是一个值，而是一个 JSONObject");
            } else if (value instanceof JSONArray) {
                ((JSONArray) value).forEach(obj -> {
                    if (obj instanceof LinkedHashMap) {
                        throw new RuntimeException("参数值中存在 JSONObject");
                    } else if (obj instanceof JSONArray) {
                        throw new RuntimeException("参数值中存在 JSONArray");
                    }
                    tmp.add(obj.toString());
                });
            } else {
                tmp.add(value.toString());
            }
            return tmp.toArray(new String[0]);
        } else if (this.contentType == MockContentType.TEXT) {
            if (StringUtils.isNotBlank(key)) {
                throw new RuntimeException(this.contentType.getName() + " 类型的请求 body 不能按参数名获取参数值");
            }
            return new String[]{(String) body};
        } else if (this.contentType == MockContentType.JAVASCRIPT || this.contentType == MockContentType.HTML || this.contentType == MockContentType.XML) {
            if (StringUtils.isNotBlank(key)) {
                throw new RuntimeException(this.contentType.getName() + " 类型的请求 body 不能按参数名获取参数值");
            }
            return new String[]{(String) body};
        }

        throw new RuntimeException("参数值不存在");
    }

    /**
     * 获取请求的 body 中的参数值
     * @param key 参数名
     * @return
     */
    public List<String> getBodyValue2List(String key) {
        if (this.contentType == MockContentType.FORM_DATA || this.contentType == MockContentType.X_WWW_FORM_URLENCODED) {
            if (((JSONObject) body).getJSONArray(key) == null) {
                return null;
            } else {
                return ((JSONObject) body).getJSONArray(key).toJavaList(String.class);
            }
        } else if (this.contentType == MockContentType.JSON) {
            JsonHelper jsonHelper = new JsonHelper(JSON.toJSONString(this.body));
            ArrayList<String> tmp = new ArrayList<>();
            if (jsonHelper == null) {
                return null;
            }
            Object value = jsonHelper.get(key.trim());
            if (value == null) {
                return null;
            } else if (value instanceof LinkedHashMap) {
                throw new RuntimeException("参数不是一个值，而是一个 JSONObject");
            } else if (value instanceof JSONArray) {
                ((JSONArray) value).forEach(obj -> {
                    if (obj instanceof LinkedHashMap) {
                        throw new RuntimeException("参数值中存在 JSONObject");
                    } else if (obj instanceof JSONArray) {
                        throw new RuntimeException("参数值中存在 JSONArray");
                    }
                    tmp.add(obj.toString());
                });
            } else {
                tmp.add(value.toString());
            }
            return tmp;
        } else if (this.contentType == MockContentType.TEXT) {
            if (StringUtils.isNotBlank(key)) {
                throw new RuntimeException(this.contentType.getName() + " 类型的请求 body 不能按参数名获取参数值");
            }
            ArrayList<String> tmp = new ArrayList<>();
            tmp.add((String) body);
            return tmp;
        } else if (this.contentType == MockContentType.JAVASCRIPT || this.contentType == MockContentType.HTML || this.contentType == MockContentType.XML) {
            if (StringUtils.isNotBlank(key)) {
                throw new RuntimeException(this.contentType.getName() + " 类型的请求 body 不能按参数名获取参数值");
            }
            ArrayList<String> tmp = new ArrayList<>();
            tmp.add((String) body);
            return tmp;
        }

        throw new RuntimeException("参数值不存在");
    }

    /**
     * 返回请求的 body 中的一个参数值
     * @param key 参数名
     * @return
     */
    public String getBodyValue2String(String key) {
        if (this.contentType == MockContentType.FORM_DATA || this.contentType == MockContentType.X_WWW_FORM_URLENCODED) {
            if (((JSONObject) body).getJSONArray(key) == null) {
                return null;
            } else if (((JSONObject) body).getJSONArray(key).size() > 1) {
                throw new RuntimeException("参数值不唯一");
            } else if (((JSONObject) body).getJSONArray(key).size() == 1) {
                return ((JSONObject) body).getJSONArray(key).get(0).toString();
            } else {
                return null;
            }
        } else if (this.contentType == MockContentType.JSON) {
            JsonHelper jsonHelper = new JsonHelper(JSON.toJSONString(this.body));
            if (jsonHelper == null) {
                return null;
            }
            Object value = jsonHelper.get(key.trim());
            if (value == null) {
                return null;
            } else if (value instanceof LinkedHashMap) {
                throw new RuntimeException("参数不是一个值，而是一个 JSONObject");
            } else if (value instanceof JSONArray) {
                throw new RuntimeException("参数不是一个值，而是一个 JSONArray");
            }
            return value.toString();
        } else if (this.contentType == MockContentType.TEXT) {
            if (StringUtils.isNotBlank(key)) {
                throw new RuntimeException(this.contentType.getName() + " 类型的请求 body 不能按参数名获取参数值");
            }
            return (String) body;
        } else if (this.contentType == MockContentType.JAVASCRIPT || this.contentType == MockContentType.HTML || this.contentType == MockContentType.XML) {
            if (StringUtils.isNotBlank(key)) {
                throw new RuntimeException(this.contentType.getName() + " 类型的请求 body 不能按参数名获取参数值");
            }
            return (String) body;
        }

        throw new RuntimeException("参数值不存在");
    }
}
